﻿namespace Baddies.Utils
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using Baddies.Events;    

    /// <summary>
    /// Singleton class for printing debugging messages to a
    /// log file.
    /// </summary>
    public class Log
    {
        /// <summary>
        /// Instance variable for the singleton pattern.
        /// </summary>
        private static Log instance = new Log();

        /// <summary>
        /// Writter for creating files.
        /// </summary>
        private TextWriter writter = null;

        /// <summary>
        /// Indicates whether to send the log to the in-game textoutput as well.
        /// </summary>
        private bool peekLog;

        /// <summary>
        /// Prevents a default instance of the Log class from being created.
        /// </summary>
        private Log() 
        {
            this.peekLog = false;
            EventManager.GetEV.RegisterNewEvent("PeekLog", false);
            EventManager.GetEV.Register("PeekLog", this.PeekLogDelegate);

            this.writter = new StreamWriter("baddiesLog.txt");
            this.writter.WriteLine(DateTime.Now);
            this.writter.WriteLine("--------------------");
        }

        /// <summary>
        /// Gets the instance with a short-name reference ("f" for "file").
        /// </summary>
        /// <value>The singleton instance.</value>
        public static Log F
        {
            get { return instance; }
        }

        /// <summary>
        /// Writes a text to the log stream.
        /// </summary>
        /// <param name="text">Text to write.</param>
        public void Write(string text)
        {
            Debug.Assert(this.writter != null, "Log writter is null!");
            this.writter.Write(text);

            if (this.peekLog)
            {
                AddLineArg args = new AddLineArg();
                args.Text = text;
                EventManager.GetEV.Trigger("AddLine", this, args);
            }
        }

        /// <summary>
        /// Writes a text to the log stream. Adds a linebreak at the end.
        /// </summary>
        /// <param name="text">Text to write.</param>
        public void WriteLine(string text)
        {
            Debug.Assert(this.writter != null, "Log writter is null!");
            this.writter.WriteLine(text);

            if (this.peekLog)
            {
                AddLineArg args = new AddLineArg();
                args.Text = text + System.Environment.NewLine;
                EventManager.GetEV.Trigger("AddLine", this, args);
            }
        }

        /// <summary>
        /// Closes the writting stream. To be called once the logging is done.
        /// </summary>
        public void Close()
        {
            this.writter.Close();
            this.writter = null;
        }

        /// <summary>
        /// Delegate function for the ConsoleMsg event.
        /// </summary>
        /// <param name="sender">Sender of the request.</param>
        /// <param name="e">PeekLog parameter.</param>
        private void PeekLogDelegate(object sender, EventArgs e)
        {
            this.peekLog = ((PeekLogArg)e).PeekLog;
        }
    }
}
